// error-monitor-sdk 主体实现
// 提供 SDK 的初始化、事件监听、手动上报、状态获取、销毁等核心功能

// 导入类型定义和依赖
import { SDKConfig, ErrorInfo, PerformanceInfo, BehaviorInfo, EventListener, ErrorMonitorSDK } from './types'; // 导入类型
import { ErrorMonitor } from './monitors/errorMonitor'; // 导入错误监控器
import { PerformanceMonitor } from './monitors/performanceMonitor'; // 导入性能监控器
import { BehaviorMonitor } from './monitors/behaviorMonitor'; // 导入行为监控器
import { Reporter } from './reporters/reporter'; // 导入上报器

/**
 * ErrorMonitorSDKImpl
 * 错误监控SDK主类，实现初始化、事件监听、手动上报、状态获取、销毁等功能
 */
export class ErrorMonitorSDKImpl implements ErrorMonitorSDK {
  private config: SDKConfig | null = null; // SDK配置
  private errorMonitor: ErrorMonitor | null = null; // 错误监控器实例
  private performanceMonitor: PerformanceMonitor | null = null; // 性能监控器实例
  private behaviorMonitor: BehaviorMonitor | null = null; // 行为监控器实例
  private reporter: Reporter | null = null; // 上报器实例
  private eventListeners: {
    error: EventListener[]; // 错误事件监听器
    performance: EventListener[]; // 性能事件监听器
    behavior: EventListener[]; // 行为事件监听器
  } = {
    error: [],
    performance: [],
    behavior: []
  };
  private isInitialized = false; // 是否已初始化

  /**
   * 初始化SDK
   * @param config SDKConfig 配置项，包含上报地址、应用ID等
   */
  public init(config: SDKConfig): void {
    if (this.isInitialized) {
      console.warn('Error monitor SDK: Already initialized'); // 已初始化警告
      return;
    }
    // 验证配置
    if (!config.reportUrl) {
      throw new Error('reportUrl is required'); // 缺少上报地址
    }
    if (!config.appId) {
      throw new Error('appId is required'); // 缺少应用ID
    }
    this.config = {
      enableConsole: false, // 默认关闭console监控
      enablePerformance: true, // 默认开启性能监控
      enableBehavior: false, // 默认关闭行为监控
      sampleRate: 1, // 默认全量采样
      maxCacheSize: 100, // 默认最大缓存100
      reportInterval: 5000, // 默认5秒上报
      ...config // 合并用户配置
    };
    this.reporter = new Reporter(this.config); // 创建上报器
    this.errorMonitor = new ErrorMonitor(
      this.config,
      (error: ErrorInfo) => {
        this.reporter?.reportError(error); // 上报错误
        this.emit('error', error); // 触发事件
      }
    );
    if (this.config.enablePerformance) {
      this.performanceMonitor = new PerformanceMonitor(
        this.config,
        (performance: PerformanceInfo) => {
          this.reporter?.reportPerformance(performance); // 上报性能
          this.emit('performance', performance); // 触发事件
        }
      );
    }
    if (this.config.enableBehavior) {
      this.behaviorMonitor = new BehaviorMonitor(
        this.config,
        (behavior: BehaviorInfo) => {
          this.reporter?.reportBehavior(behavior); // 上报行为
          this.emit('behavior', behavior); // 触发事件
        }
      );
    }
    this.errorMonitor.init(); // 初始化错误监控器
    this.performanceMonitor?.init(); // 初始化性能监控器
    this.behaviorMonitor?.init(); // 初始化行为监控器
    this.setupPageUnloadHandler(); // 监听页面卸载
    this.isInitialized = true; // 标记为已初始化
    console.log('Error monitor SDK initialized successfully'); // 初始化成功日志
  }

  /**
   * 手动上报错误
   * @param error Error对象或错误信息字符串
   * @param extra 附加信息
   */
  public reportError(error: Error | string, extra?: Record<string, any>): void {
    if (!this.isInitialized) {
      console.warn('Error monitor SDK: Not initialized'); // 未初始化警告
      return;
    }
    this.errorMonitor?.reportError(error, extra); // 调用错误监控器
  }

  /**
   * 手动上报性能信息
   * @param performance 性能数据对象
   */
  public reportPerformance(performance: PerformanceInfo): void {
    if (!this.isInitialized) {
      console.warn('Error monitor SDK: Not initialized'); // 未初始化警告
      return;
    }
    this.performanceMonitor?.reportPerformance(performance); // 调用性能监控器
  }

  /**
   * 手动上报用户行为
   * @param behavior 行为数据对象
   */
  public reportBehavior(behavior: BehaviorInfo): void {
    if (!this.isInitialized) {
      console.warn('Error monitor SDK: Not initialized'); // 未初始化警告
      return;
    }
    this.behaviorMonitor?.reportBehavior(behavior); // 调用行为监控器
  }

  /**
   * 添加事件监听器
   * @param event 事件类型（error/performance/behavior）
   * @param listener 事件回调函数
   */
  public on(event: 'error' | 'performance' | 'behavior', listener: EventListener): void {
    this.eventListeners[event].push(listener); // 添加到监听器数组
  }

  /**
   * 移除事件监听器
   * @param event 事件类型
   * @param listener 事件回调函数
   */
  public off(event: 'error' | 'performance' | 'behavior', listener: EventListener): void {
    const listeners = this.eventListeners[event]; // 获取监听器数组
    const index = listeners.indexOf(listener); // 查找索引
    if (index > -1) {
      listeners.splice(index, 1); // 移除监听器
    }
  }

  /**
   * 触发事件
   * @param event 事件类型
   * @param data 事件数据
   */
  private emit(event: 'error' | 'performance' | 'behavior', data: ErrorInfo | PerformanceInfo | BehaviorInfo): void {
    this.eventListeners[event].forEach(listener => {
      try {
        listener(data); // 调用监听器
      } catch (error) {
        console.warn('Error monitor SDK: Event listener error', error); // 监听器异常
      }
    });
  }

  /**
   * 设置页面卸载处理器，确保缓存数据上报
   */
  private setupPageUnloadHandler(): void {
    const handlePageUnload = () => {
      this.reporter?.sendBeacon(); // 页面卸载时上报缓存
    };
    window.addEventListener('beforeunload', handlePageUnload); // 监听beforeunload
    window.addEventListener('unload', handlePageUnload); // 监听unload
    window.addEventListener('pagehide', handlePageUnload); // 监听pagehide
    document.addEventListener('visibilitychange', () => {
      if (document.visibilityState === 'hidden') {
        this.reporter?.sendBeacon(); // 页面隐藏时上报缓存
      }
    });
  }

  /**
   * 获取SDK当前状态
   * @returns 状态对象，包括初始化状态、配置、缓存状态
   */
  public getStatus(): {
    isInitialized: boolean; // 是否已初始化
    config: SDKConfig | null; // 当前配置
    cacheStatus: {
      errorCount: number; // 错误缓存数
      performanceCount: number; // 性能缓存数
      behaviorCount: number; // 行为缓存数
    } | null;
  } {
    return {
      isInitialized: this.isInitialized, // 初始化状态
      config: this.config, // 当前配置
      cacheStatus: this.reporter?.getCacheStatus() || null // 缓存状态
    };
  }

  /**
   * 强制上报缓存数据
   */
  public flush(): void {
    if (!this.isInitialized) {
      console.warn('Error monitor SDK: Not initialized'); // 未初始化警告
      return;
    }
    this.reporter?.flush(); // 调用上报器
  }

  /**
   * 销毁SDK，移除所有监听和缓存
   */
  public destroy(): void {
    if (!this.isInitialized) {
      return; // 未初始化直接返回
    }
    this.errorMonitor?.destroy(); // 销毁错误监控器
    this.performanceMonitor?.destroy(); // 销毁性能监控器
    this.behaviorMonitor?.destroy(); // 销毁行为监控器
    this.reporter?.destroy(); // 销毁上报器
    this.eventListeners.error = []; // 清空错误监听器
    this.eventListeners.performance = []; // 清空性能监听器
    this.eventListeners.behavior = []; // 清空行为监听器
    this.config = null; // 清空配置
    this.errorMonitor = null; // 清空实例
    this.performanceMonitor = null;
    this.behaviorMonitor = null;
    this.reporter = null;
    this.isInitialized = false; // 标记为未初始化
    console.log('Error monitor SDK destroyed'); // 销毁日志
  }
}

// 创建全局SDK实例
let globalSDK: ErrorMonitorSDKImpl | null = null; // 全局变量

// 创建SDK实例的工厂函数
export function createErrorMonitorSDK(): ErrorMonitorSDK {
  if (!globalSDK) {
    globalSDK = new ErrorMonitorSDKImpl(); // 实例化
  }
  return globalSDK; // 返回实例
}

// 获取全局SDK实例
export function getErrorMonitorSDK(): ErrorMonitorSDK | null {
  return globalSDK; // 返回全局实例
}

// 默认导出
export default createErrorMonitorSDK; // 默认导出工厂函数 